Pure-julia OpenAPI internals rewrite - #103
Conversation
Replace the legacy generated-client and server implementation with the normalized OpenAPI 3.0, 3.1, and 3.2 pipeline. Keep the provisional JSON Schema engine isolated inside OpenAPI. Generate clients against that engine until its API is ready to move upstream. Keep HTTP optional through an extension. Leave server framework integration to downstream packages such as Servo. Add adversarial, conformance, external-corpus, runtime HTTP, and JuliaC trim-compilation coverage. BREAKING CHANGE: The legacy OpenAPI 0.2 API is replaced by the namespaced document and client-generation API.
Add OpenAPI.serverplan and OpenAPI.server(source; framework, name, path), mirroring the plan/client pipeline. Split the generated runtime into a direction-agnostic common segment plus client and server segments; the server segment adds the inverse codecs (path/query/cookie style decoders, form-urlencoded and multipart/form-data request readers, and a descriptor-driven response encoder) with request-direction schema validation and structured 400/415 error responses. Framework glue is dispatched through the new OpenAPI.server_source extension seam: OpenAPIHTTPExt emits HTTP.Router modules whose register!(router, impl; path_prefix, middleware) entry point and handler contract match the shape OpenAPI.jl 0.2.x julia-server users implement stubs against (register alias included). Server planning rejects what cannot be decoded faithfully: non-form-data multipart request bodies and operations with more than one exploded object query or cookie parameter. Parameter descriptors gain a shape field and media descriptors a fields element so single-valued exploded arrays decode as arrays; header scalar error messages are direction-neutral now that both directions share them. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
RFC 3339 requires an offset, but naive timestamps are what most JSON serializers print, so strict decoding rejected a large share of deployed APIs. Be liberal on input: a missing offset now means UTC — the same convention _encode already applies when it stamps naive DateTimes with Z. Malformed values and partial offsets still raise DecodeError. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Thanks @quinnj . I did some trials with the new client. Majority of the specs that I tried work fine. But here are a few things which I feel should be addressed:
I will also try this out with some more complicated specs, maybe the k8s api spec. |
Address tanmaykm's production trial feedback on the rewrite: - An undocumented 2XX status no longer throws: an empty body returns nothing and a payload returns raw bytes. Undocumented error statuses still throw ApiError. - A response with no Content-Type decodes by status alone, as does a misreported Content-Type when only one media type is documented for the status. UnexpectedContentType is reserved for genuinely ambiguous multi-media responses. - A new datetime = :zoned generation option maps format: date-time to TimeZones.ZonedDateTime with offsets preserved end to end; the default Dates.DateTime mapping continues to normalize RFC 3339 offsets to UTC. - A new stream_to::Channel keyword on every generated operation streams response bodies incrementally over HTTP.open: consecutive JSON documents, JSON lines, RFC 7464 records, text lines, or raw chunks, each decoded to the documented response type. The call returns at the response head; closing the channel from the consumer aborts the transfer. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Content keys that differ only in parameters are separate entries, not case-insensitive duplicates: the Kubernetes OpenAPI v3 documents pair application/json with application/json;stream=watch on every list operation, and the duplicate check previously rejected the whole document. Compare the full lowercased key instead of the stripped base type. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Thanks for the thorough trial run, @tanmaykm — all four points are addressed as of ac0689d: Undocumented response codes no longer error. A Missing/misreported Content-Type falls back to decoding by status. When a response has no Time zones. Offsets like Streaming responses. Every generated operation now accepts events = Channel{Any}(16)
K8sClient.watch_core_v1_namespaced_pod(...; stream_to = events)
for event in events
...
endTest coverage added for all of the above, including a raw chunked-transfer fixture that splits items across wire chunks. I also pre-flighted the k8s trial you mentioned: the v3 documents pair [update prompted and reviewed by quinnj, posted by claude] |
Replace the legacy generated-client and server implementation with the normalized OpenAPI 3.0, 3.1, and 3.2 pipeline.
Keep the provisional JSON Schema engine isolated inside OpenAPI. Generate clients against that engine until its API is ready to move upstream.
Keep HTTP optional through an extension. Leave server framework integration to downstream packages such as Servo.
Add adversarial, conformance, external-corpus, runtime HTTP, and JuliaC trim-compilation coverage.
BREAKING CHANGE: The legacy OpenAPI 0.2 API is replaced by the namespaced document and client-generation API.